//Decompiled by DJ v3.10.10.93 Copyright 2007 Atanas Neshkov  Date: 27/11/2008 22:58:49
//Home Page: http://members.fortunecity.com/neshkov/dj.html  http://www.neshkov.com/dj.html - Check often for new version!
//Decompiler options: packimports(3) 
//Source File Name:   MainWindow.java

package reversi;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;

import javax.swing.*;
import java.lang.reflect.Constructor;

//Referenced classes of package reversi:
//ReversiAlgorithm, GameState, Move, StartDialog, 
//GameGrid, HumanAlgorithm, Game, Initializer

public class MainWindow extends JFrame
implements ActionListener, PropertyChangeListener
{
	Pesos pesos = new Pesos();
	int firstPlayer=0;
	MeuTreinamento meuTreinamento;
	int numeroDeTreinos=0;

	public MainWindow(int i)
	{
		super("Reversi");
		if(icons[0] == null || icons[1] == null)
		{
			Toolkit toolkit = Toolkit.getDefaultToolkit();
			icons[0] = new ImageIcon(toolkit.getImage("images/vaalea.gif"));
			icons[1] = new ImageIcon(toolkit.getImage("images/tumma.gif"));
			icons[2] = new ImageIcon(toolkit.getImage("images/pieni_vaalea.gif"));
			icons[3] = new ImageIcon(toolkit.getImage("images/pieni_tumma.gif"));
		}

		currentState = new GameState(i);
		gameGrid = new GameGrid(currentState);
		gameGrid.setForeground(Color.lightGray);
		getContentPane().add(gameGrid, "Center");
		JToolBar jtoolbar = new JToolBar();
		jtoolbar.setFloatable(false);
		jtoolbar.setLayout(new BoxLayout(jtoolbar, 0));
		progressBar = new JProgressBar();
		jtoolbar.add(progressBar);
		lblScore = new JLabel("2-2");
		jtoolbar.add(Box.createHorizontalStrut(10));
		jtoolbar.add(lblScore);
		Dimension dimension = new Dimension(100, 20);
		progressBar.setMaximumSize(dimension);
		progressBar.setPreferredSize(dimension);
		lblInfo = new JLabel("Welcome.");
		jtoolbar.add(Box.createHorizontalGlue());
		jtoolbar.add(lblInfo);
		getContentPane().add(jtoolbar, "South");
		JMenuBar jmenubar = new JMenuBar();
		setJMenuBar(jmenubar);
		JMenu jmenu = new JMenu("Game");
		jmenubar.add(jmenu);
		mnuStart = new JMenuItem("New ...");
		mnuStart.setActionCommand("start");
		mnuStart.addActionListener(this);
		jmenu.add(mnuStart);
		mnuStop = new JMenuItem("Stop");
		mnuStop.setActionCommand("stop");
		mnuStop.setEnabled(false);
		mnuStop.addActionListener(this);
		jmenu.add(mnuStop);
		jmenu.addSeparator();
		mnuExit = new JMenuItem("Exit");
		mnuExit.setActionCommand("exit");
		mnuExit.addActionListener(this);
		jmenu.add(mnuExit);
		jmenu = new JMenu("About");
		jmenubar.add(jmenu);
		mnuInfo = new JMenuItem("About the program ...");
		mnuInfo.setActionCommand("info");
		mnuInfo.addActionListener(this);
		jmenu.add(mnuInfo);
		setDefaultCloseOperation(0);
		addWindowListener(new WindowAdapter() {

			public void windowClosing(WindowEvent windowevent)
			{
				actionPerformed(new ActionEvent(this, -1, "exit"));
			}

		}
		);
		pack();
	}

	public void actionPerformed(ActionEvent actionevent)
	{
		String s = actionevent.getActionCommand();
		if(s.equals("exit"))
		{
				System.exit(0);
		} else
			if(s.equals("start"))
			{
				this.iniciaJogo();

			} else
				if(s.equals("stop"))
					
						stopGame();
					
				else
					if(s.equals("info"))
						JOptionPane.showMessageDialog(null, "Reversi, version 0.9.5 en\nThe test platform for the Artificial Intelligence\ncourse work 2006.\n\nCopyright (C) Topi M\344enp\344\344, Timo Ahonen,\nValtteri Takala 2001-2006\n\nExtra credits for Matti Kuonanoja for the\ngame reporting method.\n\nMaking copies of this program is allowed for\nusage at the Artificial Intelligence course of\nUniversity of Oulu. Using this program or parts\nof it for other purposes is forbidden without\nan explicit permission from the authors.\n", "About the Program", 1);
	}
	
	public void iniciaJogo(){
		algorithms = new ReversiAlgorithm[2];
		currentGame = null;
		stateHistory = new GameState[64];
		moveHistory = new Move[64];
		scoreHistory = new String[64];
		numeroDeTreinos++;
		moveCount = 0;
		turnLength = 5;
		currentState.reset();
		gameGrid.repaint();
		try
		{
			meuTreinamento = new MeuTreinamento(pesos);
			algorithms[(firstPlayer)] = (ReversiAlgorithm)Class.forName("ILHA").newInstance();
			firstPlayer=(firstPlayer+1)%2;
			
			algorithms[firstPlayer]=meuTreinamento;
		}
		catch(Exception exception1)
		{
			exception1.printStackTrace();
			return;
		}
		if(currentGame != null)
			currentGame.removePropertyChangeListener(this);
		currentGame = new Game(algorithms, turnLength);
		currentGame.setCurrentPlayer(firstPlayer);
		initHistoryArrays();
		currentGame.addPropertyChangeListener(this);
		(new Initializer(algorithms[firstPlayer], currentGame, new GameState(currentState), firstPlayer, turnLength)).start();
		showPlayer();
		currentGame.start();
	}

	private void initHistoryArrays()
	{
		moveHistory[0] = new Move(-1, -1, -1);
		stateHistory[0] = new GameState(currentState);
		scoreHistory[0] = (new StringBuilder()).append(Integer.toString(stateHistory[0].getMarkCount(0))).append(" - ").append(Integer.toString(stateHistory[0].getMarkCount(1))).toString();
		for(int i = 1; i < 64; i++)
		{
			moveHistory[i] = null;
			stateHistory[i] = null;
			scoreHistory[i] = null;
		}

	}



	private void stopGame()
	{
		if(currentGame != null)
			currentGame.stopIt();
	//	mnuStart.setEnabled(true);
	//	mnuStop.setEnabled(false);
		for(int i = 0; i < 2; i++)
			if(algorithms[i] != null)
				algorithms[i].cleanup();
		try {
			printPesos();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		pesos = meuTreinamento.atualizaPesos();
		this.iniciaJogo();

	}

	private void printPesos() throws IOException {
		pesos.gravaArquivo(numeroDeTreinos);
		
	}

	private void showPlayer()
	{
		if(currentGame == null)
		{
			return;
		} else
		{
			int i = currentGame.getCurrentPlayer();
			lblScore.setText((new StringBuilder()).append(currentState.getMarkCount(0)).append("-").append(currentState.getMarkCount(1)).toString());
			lblInfo.setText(algorithms[i].getName());
			lblInfo.setIcon(icons[i + 2]);
			return;
		}
	}

	public void propertyChange(PropertyChangeEvent propertychangeevent)
	{
		String s = propertychangeevent.getPropertyName();
		if(s.equals("time"))
			progressBar.setValue((int)(((Float)propertychangeevent.getNewValue()).floatValue() * 100F));
		else
			if(s.equals("stopped."))
			{
				progressBar.setValue(0);
				lblInfo.setText("The game has ended.");
				lblInfo.setIcon(null);
				stopGame();
			} else
				if(s.equals("info"))
				{
					lblInfo.setText((String)propertychangeevent.getNewValue());
					lblInfo.setIcon(null);
				} else
					if(s.equals("disqualified"))
					{
						int i = ((Integer)propertychangeevent.getNewValue()).intValue();
						progressBar.setValue(0);
						lblInfo.setText((new StringBuilder()).append("Time is out! ").append(algorithms[i].getName()).append(" is disqualified!").toString());
						
							
						
						showWinner(i ^ 1);
						stopGame();
					} else
						if(s.equals("move"))
						{
							progressBar.setValue(0);
							Move move = (Move)propertychangeevent.getNewValue();
							if(move != null && !currentState.addMove(move))
							{
								String s1 = (new StringBuilder()).append("Error! ").append(algorithms[move.player].getName()).append(" is disqualified!\n").append("Move to square (").append(move.x).append(",").append(move.y).append(") is illegal:\n").toString();
								if(currentState.getValueAt(move.x, move.y) != 0)
									s1 = (new StringBuilder()).append(s1).append("the square is already occupied.").toString();
								else
									if(move.x < 0 || move.x >= currentState.getWidth() || move.y < 0 || move.y >= currentState.getHeight())
										s1 = (new StringBuilder()).append(s1).append("the square is outside of the board.").toString();
									else
										s1 = (new StringBuilder()).append(s1).append("no opponent's discs can be flipped.").toString();
								lblInfo.setText((new StringBuilder()).append("Error! ").append(algorithms[move.player].getName()).append(" is disqualified!").toString());
								
									
								
								// JOptionPane.showMessageDialog(null, s1, "error", 0, icons[move.player]);
								showWinner(move.player ^ 1);
								stopGame();
								return;
							}
							gameGrid.repaint();
							moveCount++;
							if(moveCount < 64)
							{
								moveHistory[moveCount] = move;
								stateHistory[moveCount] = new GameState(currentState);
								scoreHistory[moveCount] = (new StringBuilder()).append(Integer.toString(stateHistory[moveCount].getMarkCount(0))).append(" - ").append(Integer.toString(stateHistory[moveCount].getMarkCount(1))).toString();
							}
							if(currentState.getPossibleMoveCount(0) == 0 && currentState.getPossibleMoveCount(1) == 0)
							{
								lblInfo.setIcon(null);
								
									
								
								int j = currentState.getMarkCount(0);
								int l = currentState.getMarkCount(1);
								if(j == l)
								{
									currentState.reorder();
									gameGrid.repaint();
									lblInfo.setText("Tasapeli!");
									//JOptionPane.showMessageDialog(null, "The game ended in tie!", "Tie", -1);
								} else
									if(j > l)
										showWinner(0);
									else
										showWinner(1);
								stopGame();
								return;
							}
							int k = currentGame.getCurrentPlayer();
							showPlayer();
							(new Initializer(algorithms[k], currentGame, new GameState(currentState), k, turnLength)).start();
							currentGame.setReadyForNext(true);
						}
	}

	private void showWinner(int i)
	{
		gameGrid.repaint();
		try {
			pesos.printwinner(algorithms[i].getName().toUpperCase());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// JOptionPane.showMessageDialog(null, (new StringBuilder()).append("The winner is ").append(algorithms[i].getName().toUpperCase()).append("!\n(").append(currentState.getMarkCount(i)).append("-").append(currentState.getMarkCount(i ^ 1)).append(")").toString(), "Winner", -1, icons[i]);
		currentState.reorder();
	}

	public static void main(String args[])
	{
		if(args.length == 0)
			(new MainWindow(8)).setVisible(true);
		else
			try
		{
				int i = Integer.parseInt(args[0]);
				(new MainWindow(i)).setVisible(true);
		}
		catch(NumberFormatException numberformatexception)
		{
			System.out.println("Give the size of the board on the command line.");
			System.exit(1);
		}
	}

	private static final int HISTORY_ARRAY_LENGHT = 64;
	GameGrid gameGrid;
	JMenuItem mnuStart;
	JMenuItem mnuStop;
	JMenuItem mnuExit;
	JMenuItem mnuInfo;
	//StartDialog startDialog;
	JProgressBar progressBar;
	JLabel lblInfo;
	JLabel lblScore;
	int turnLength;
	int moveCount;
	ReversiAlgorithm algorithms[];
	GameState currentState;
	Game currentGame;
	static ImageIcon icons[] = new ImageIcon[4];
	private GameState stateHistory[];
	private Move moveHistory[];
	private String scoreHistory[];

}